package com.cuicui.mall.aspect;

import com.cuicui.mall.annotation.LogRecorder;
import com.cuicui.mall.dao.LogDataMapper;
import com.cuicui.mall.entity.LogData;
import com.cuicui.mall.utils.NetworkUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;

@Aspect
@Component
public class LoggerAspect {
    @Autowired
    private LogDataMapper logDataMapper;

    @Pointcut(value = "execution(* com.cuicui.mall.controller..*(..))")
    public void logPointcut() {}

    @Around("logPointcut()")
    public Object aroundLogger(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取用户请求相关信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
        HttpServletResponse response =  Objects.requireNonNull(attributes).getResponse();

        // 在日志切面或拦截器中：
        String userName = (String) request.getAttribute("CURRENT_USER_NAME");

        // 解析请求信息
        String ip = NetworkUtil.getClientIPByHeader(request);
        String method  = request.getMethod();

        // 执行目标方法并捕获状态码
        Object result;
        int statusCode = HttpServletResponse.SC_OK; // 默认200
        try {
            result = joinPoint.proceed();
            statusCode = response.getStatus(); // 获取实际状态码
        } catch (Exception e) {
            statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; // 500
            throw e;
        } finally {
            // 记录日志（含状态码）
            Method methodObj = ((MethodSignature) joinPoint.getSignature()).getMethod();
            LogRecorder logRecorder = methodObj.getAnnotation(LogRecorder.class);
            if (logRecorder != null) {
                LogData logData = new LogData();
                logData.setStatusCode(String.valueOf(statusCode));
                logData.setCreateTime(new Date());
                logData.setIp(ip);
                logData.setUserName(userName);
                logData.setMethods(method);
                logData.setUserAgent(request.getHeader("User-Agent"));
                logData.setContent(logRecorder.operation());
                logData.setRequestedUrl(request.getRequestURI());
                logDataMapper.insert(logData);
            }
        }
        return result;
    }
}
